﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading;
using System.Windows.Threading;
using SweeperPrototype.GUI.Behaviors;
using SweeperPrototype.GUI.Behaviors.AttachedCommand;
using SweeperPrototype.GUI.Positions;
using SweeperPrototype.Objects;

namespace SweeperPrototype.GUI
{
    public class PositionListViewModel : BaseVM
    {
        private readonly ObservableCollection<PositionViewModel> m_Positions;
        private readonly NotifyList<PositionSubscription> m_CorePositions;
        private readonly NotifyList<PositionViewModel>  m_SelectedViewModels;
        private readonly NotifyList<PositionSubscription> m_SelectedPositions;
        private readonly DispatcherSynchronizationContext m_Context;

        private readonly SimpleCommand m_GridSelectionHandler;
        public PositionListViewModel( NotifyList<PositionSubscription> core_positions )
        {
            m_Context = new DispatcherSynchronizationContext();
            m_SelectedViewModels = new NotifyList<PositionViewModel>();

            m_CorePositions = core_positions;
            m_SelectedPositions = new NotifyList<PositionSubscription>();
            m_Positions = new ObservableCollection<PositionViewModel>();

            m_CorePositions.Addition += HandleCorePositionAdded;
            m_CorePositions.Removal += HandleCorePositionRemoved;

            // TODO: clean this up. Its fugly.
            m_GridSelectionHandler = new SimpleCommand( o => true,
                delegate(object o)
                    {

                        ObservableCollection<Object> collection = o as ObservableCollection<Object>;

                        List<PositionViewModel> removal_list = new List<PositionViewModel>(m_SelectedViewModels);

                        foreach (PositionViewModel p in collection)
                        {
                            if (removal_list.Remove(p) == false)
                            {
                                m_SelectedViewModels.Add(p);
                                m_SelectedPositions.Add(p.CorePositionSubscription);
                            }
                        }

                        foreach (PositionViewModel position_view_model in removal_list)
                        {
                            // todo: use indexes instead.
                            m_SelectedViewModels.Remove(position_view_model);
                            m_SelectedPositions.Remove(position_view_model.CorePositionSubscription);
                        }

                    }
                );
        }

        public SimpleCommand GridSelectionHandler
        {
            get { return m_GridSelectionHandler; }
        }

        public ObservableCollection<PositionViewModel> Positions
        {
            get { return m_Positions; }
        }

        public INotifyList<PositionSubscription> SelectedPositions
        {
            get { return m_SelectedPositions; }
        }


        //public int Count
        //{
        //    get { return m_Positions.Count; }
        //}

        private void HandleCorePositionRemoved(PositionSubscription removal, int index)
        {
            m_Context.Post(
                delegate
                    {
                        m_Positions.RemoveAt(index);
                    }, null );
        }

        private void HandleCorePositionAdded(PositionSubscription addition, int index) {
            
            //if( Dispatcher.CurrentDispatcher.CheckAccess() == false )
            //{
                m_Context.Post(
                    delegate
                        {

                            PositionViewModel position_view_model = new PositionViewModel(addition);
                            //position_view_model.PropertyChanged += HandleViewModelChanged;
                            
                            if (index < m_Positions.Count)
                            {
                                m_Positions.Insert(index, position_view_model);
                            }
                            else
                            {
                                m_Positions.Add(position_view_model);
                            }
                        },
                    null
                    );

            //}
            //else
            //{

            //}
        }

        //private void HandleViewModelChanged(object sender, PropertyChangedEventArgs args)
        //{
        //    if( args == PositionViewModel.ARGS_ISSELECTED )
        //    {
        //        PositionViewModel position_view_model = (PositionViewModel) sender;
        //        if( position_view_model.IsSelected )
        //        {
        //            m_SelectedViewModels.Add( position_view_model );
        //            m_SelectedPositions.Add( position_view_model.CorePositionSubscription );
        //        }
        //        else
        //        {
        //            m_SelectedViewModels.Remove( position_view_model );
        //            m_SelectedPositions.Remove(position_view_model.CorePositionSubscription);
        //        }
        //    }
        //}

    }
}
